namespace cpputils
{

template<class TYPE>
class simple_graph
{
public:
	struct edge
	{
		TYPE value;
		int to;
		int inv_index;
	};
	typedef vector<edge> edge_list;

	void clear()
	{
		reset_vector(Graph);
	}
	void set_size(int SetSize)
	{
		clear();
		Graph.resize(SetSize);
	}
	void add_edge(int A, int B, const TYPE& Value)
	{
		assert(A != B);
		edge Edge;
		Edge.to = B;
		Edge.inv_index = Graph[B].size();
		Edge.value = Value;
		Graph[A].push_back(Edge);
		Edge.to = A;
		Edge.inv_index = Graph[A].size() - 1;
		Graph[B].push_back(Edge);
	}
	void remove_vertex(int A)
	{
		edge_list& List = Graph[A];
		for (int I = 0; I < (int)List.size(); I++)
		{
			int B = List[I].to;
			int InvIndex = List[I].inv_index;
			if (InvIndex < (int)Graph[B].size() - 1)
			{
				edge& InvEdge = Graph[B][InvIndex];
				InvEdge = Graph[B].back();
				int C = InvEdge.to;
				Graph[C][InvEdge.inv_index].inv_index = InvIndex;
			}
			Graph[B].pop_back();
		}
		reset_vector(List);
	}
	const vector<edge>& operator[](int A) const
	{
		return Graph[A];
	}
	vector<edge>& operator[](int A)
	{
		return Graph[A];
	}

private:
	vector<edge_list> Graph;
};

}
